#!/bin/bash
# File checked with ShellCheck (https://www.shellcheck.net/)

#/ Kurento Module scaffolding tool.
#/
#/ This tool is used to create an initial project structure that can be used
#/ as the basis to develop a new Kurento module.
#/
#/
#/ Usage
#/ -----
#/
#/ kurento-module-scaffold <ModuleName> <OutputDir> [IsOpenCV]
#/
#/
#/ Arguments
#/ ---------
#/
#/ <ModuleName>
#/
#/   Name of the new module that will be generated, in UpperCamelCase (also
#/   known as PascalCase).
#/
#/   Example: "MyNewModule".
#/
#/   Required.
#/
#/ <OutputDir>
#/
#/   Directory where the autogenerated files should be placed.
#/   Will be created if it doesn't exist.
#/
#/   Required.
#/
#/ [IsOpenCV]
#/
#/   Set to anything (for example, "1" or "true") to indicate that an OpenCV
#/   module should be prepared. Otherwise, if nothing is provided, a GStreamer
#/   module will be prepared.
#/
#/   Optional. Default: None.

# Bash options for strict error checking
set -o errexit -o errtrace -o pipefail -o nounset

# Help message (extracted from script headers)
function usage { grep '^#/' "$0" | cut --characters=4-; exit 0; }
REGEX='(^|\W)(-h|--help)($|\W)'
[[ "$*" =~ $REGEX ]] && usage
[[ $# -lt 2 ]] && usage

# Exit trap
# This runs at the end, or upon any error (thanks to 'errexit')
on_exit() {
    { _RC="$?"; } 2>/dev/null
    if ((_RC)); then echo "ERROR ($_RC)"; else echo "SUCCESS"; fi
}
trap on_exit EXIT

# Parse arguments
camelName="${1:-MyNewModule}"
name="$(echo "$camelName" | sed -e 's/\([A-Z]\)/\L\1/g')"
nameUndersScoreLower="$(echo "$camelName" | sed -e 's/\([A-Z]\)/_\L\1/g' -e 's/^_//')"
nameScoreLower="$(echo "$camelName" | sed -e 's/\([A-Z]\)/-\L\1/g' -e 's/^-//')"
nameUnderscoreUpper="$(echo "$nameUndersScoreLower" | sed -e 's/\([a-z]\)/\U\1/g')"

outputDir="${2:-myOutputDir}"

if [[ -n "${3:-}" ]]; then
    isOpenCVFilter="true"
else
    isOpenCVFilter="false"
fi

# Change to output directory
mkdir -p "$outputDir"
pushd "$outputDir" >/dev/null

# Create directory for module
mkdir "$nameScoreLower"
pushd "$nameScoreLower" >/dev/null

git init

# Create folder tree
mkdir src
pushd src >/dev/null

currentDir="@CMAKE_INSTALL_PREFIX@/share/kurento/scaffold"

cat "$currentDir/CMakeLists_server.txt.template" >"CMakeLists.txt"

if [[ "$isOpenCVFilter" != "true" ]]; then
    mkdir gst-plugins
    cat "$currentDir/CMakeLists_server_plugin.txt.template" >>"CMakeLists.txt"

    pushd gst-plugins >/dev/null

    sed \
        -e "s/\${name}/$name/g" \
        -e "s/\${nameUnderscoreUpper}/$nameUnderscoreUpper/g" \
        "$currentDir/CMakeLists_plugin.txt.template" \
        >"CMakeLists.txt"

    sed \
        -e "s/\${name}/$name/g" \
        -e "s/\${nameUndersScoreLower}/$nameUndersScoreLower/g" \
        "$currentDir/plugin.c.template" \
        >"$name.c"

    sed \
        -e "s/\${nameUndersScoreLower}/$nameUndersScoreLower/g" \
        -e "s/\${nameUnderscoreUpper}/$nameUnderscoreUpper/g" \
        -e "s/\${camelName}/$camelName/g" \
        "$currentDir/gstplugin.h.template" \
        >"gst$name.h"

    sed \
        -e "s/\${name}/$name/g" \
        -e "s/\${nameUndersScoreLower}/$nameUndersScoreLower/g" \
        -e "s/\${nameUnderscoreUpper}/$nameUnderscoreUpper/g" \
        -e "s/\${camelName}/$camelName/g" \
        "$currentDir/gstplugin.cpp.template" \
        >"gst$name.cpp"

    popd >/dev/null # gst-plugins
fi

mkdir server
pushd server >/dev/null

mkdir implementation

mkdir interface
pushd interface >/dev/null

sed \
    -e "s/\${name}/$name/" \
    "$currentDir/filter.kmd.json.template" \
    >"$name.kmd.json"

if [[ "$isOpenCVFilter" != "true" ]]; then
    sed \
        -e "s/\${name}/$name/" \
        -e "s/\${camelName}/$camelName/" \
        -e "s/\${extends}/Filter/" \
        "$currentDir/filter.Filter.kmd.json.template" \
        >"$name.$camelName.kmd.json"
else
    sed \
        -e "s/\${name}/$name/" \
        -e "s/\${camelName}/$camelName/" \
        -e "s/\${extends}/OpenCVFilter/" \
        "$currentDir/filter.Filter.kmd.json.template" \
        >"$name.$camelName.kmd.json"
fi

popd >/dev/null # interface

cat "$currentDir/CMakeLists_src.txt.template" >"CMakeLists.txt"

popd >/dev/null # server

popd >/dev/null # src

sed \
    -e "s/\${nameUnderscoreUpper}/$nameUnderscoreUpper/" \
    "$currentDir/config.h.cmake.template" \
    >"config.h.cmake"

sed \
    -e "s/\${nameScoreLower}/$nameScoreLower/" \
    "$currentDir/CMakeLists_root.txt.template" \
    >"CMakeLists.txt"

# Create a "debian/" directory for creation of .deb package files
mkdir debian
pushd debian >/dev/null

echo "9" >"compat"
touch copyright
touch docs

sed \
    -e "s/\${nameScoreLower}/$nameScoreLower/" \
    -e "s/\${date}/$(date -R)/" \
    "$currentDir/debian-changelog.template" \
    >"changelog"

sed \
    -e "s/\${nameScoreLower}/$nameScoreLower/" \
    "$currentDir/debian-control.template" \
    >"control"

cat "$currentDir/debian-rules.template" >"rules"

if [[ "$isOpenCVFilter" != "true" ]]; then
    cat "$currentDir/debian-name.install.template" >"$nameScoreLower.install"
else
    cat "$currentDir/debian-name.install.OpenCV.template" >"$nameScoreLower.install"
fi

cat "$currentDir/debian-name-dev.install.template" >"$nameScoreLower-dev.install"

mkdir source
echo "3.0 (native)" >"source/format"

popd >/dev/null # debian

echo "build/" >".gitignore"
echo "debian/$nameUndersScoreLower" >>".gitignore"

git add CMakeLists.txt src .gitignore config.h.cmake debian
git commit -m "Initial commit"

echo "Scaffolding tree created successfully"
